from django.contrib.postgres.search import SearchVector #搜索向量
from .forms import EmailPostForm, CommentForm, SearchForm
from django.shortcuts import render,get_object_or_404
from django.core.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
from .models import Post
from .forms import EmailPostForm
from .forms import EmailPostForm, CommentForm
from taggit.models import Tag
from django.db.models import Count

# Create your views here.
#增加tag_slug请求参数，默认为None
def post_list(request,tag_slug=None):
    posts = Post.published.all()
    #创建变量tag，用于存储下方代码获取的标签
    tag = None
    if tag_slug:
        tag = get_object_or_404(Tag,slug=tag_slug)
        posts = posts.filter(tags=tag)

    paginator = Paginator(posts,3)
    page = request.GET.get('page')
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    return render(request,'blog/post/list.html',{'posts':posts,'page':page,'tag':tag})

def post_detail(request, year, month, day, post):
    #确定文章实例
    post = get_object_or_404(Post, slug=post, status='published',
                             publish__year=year,
                             publish__month=month,
                             publish__day=day)
    comments = post.comments.filter(active=True)
    new_comment = None #xinpinglunbianliang 
 
    if request.method == 'POST':
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.post = post
            new_comment.save()
    else:
        comment_form = CommentForm()
    


    # 找到所有相似文章
    # 找到当前文章的标签编号，查询集合
    post_tags_ids = post.tags.values_list('id',flat=True)
    # 找到包含当前文章任意标签的文章集合（除当前文章外）用于筛选那些其标签 ID 
    # 存在于 post_tags_ids 列表中的文章
    similar_posts = Post.published.filter(tags__in=post_tags_ids)\
                    .exclude(id=post.id)
    # 对相似文章按照相同标签数量进行排序，取前 4 个，相同标签数量使用聚合函数 Count
    # 计算后保存在 same_tags 中，以便后续使用
    similar_posts = similar_posts.annotate(same_tags=Count('tags'))\
                    .order_by('-same_tags','-publish')[:4]

    #将评论传递给模板
    return render(request, 'blog/post/detail.html', {
        'post': post,
        'comments': comments,
        'new_comment': new_comment,
        'comment_form': comment_form,
        'similar_posts': similar_posts
    })
            
            
def post_share(request,post_id):
    post = get_object_or_404(Post,id=post_id,status='published')
    sent = False
    if request.method =='POST':
        form = EmailPostForm(request.POST)
        if form.is_valid():

            cd = form.cleaned_data
            post_url = request.build_absolute_uri(post.get_absolute_url())
            subject = f"{cd['name']} recommends you read " \
                f"{post.title}"
            message = f"Read {post.title} at {post_url}\n\n" \
                f"{cd['name']}\'s comments:{cd['comments']}"
            send_mail(subject,message,'1559323312@qq.com',
                [cd['to']])
            sent = True
    else:
        form = EmailPostForm()
    return render(request,'blog/post/share.html',{'post':post,'form':form,'sent':sent})

#创建 post_search 视图函数，用于处理搜索逻辑
def post_search(request):
    form = SearchForm()
    query = None
    results = []
    # 如果请求中有query字段则获取表单中的数据进行处理
    if 'query' in request.GET:
        # 获取表单
        form = SearchForm(request.GET)
        # 如果表单中的数据验证通过，即有效，则获取并处理
        if form.is_valid():
            # 获取搜索内容保存下来
            query = form.cleaned_data['query']
            # 根据标题和正文字段构建搜索向量并生成搜索字段，再根据搜索内容筛选出匹配内容保存
            results = Post.published.annotate(
                search=SearchVector('title', 'body') #将标题与正文两个字段构建为搜索向量存在临时创建的 search 字段
            ).filter(search=query) #对 search 字段进行筛选过滤
    # 将搜索结果渲染到搜索模板并返回
    return render(request, 'blog/post/search.html', {
        'form': form,
        'query': query,
        'results': results
    })